<html>
<head><meta charset="utf-8"><title>What does StdinLock borrow from Stdin? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html">What does StdinLock borrow from Stdin?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="238995660"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/238995660" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#238995660">(May 16 2021 at 18:01)</a>:</h4>
<p>i can't seem to use <code>io::stdin().lock()</code> without explicitly binding <code>io::stdin()</code> in that scope. i've seen other explanations of this problem, but none that clearly identify exactly what is still borrowed from <code>Stdin</code>. the closest i can think of is that <code>Stdin::lock()</code> has <code>-&gt; StdinLock&lt;'_&gt;</code>, which might make the borrow checker think that <code>StdinLock</code> holds a ref to something in <code>Stdin</code></p>



<a name="238996010"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/238996010" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#238996010">(May 16 2021 at 18:06)</a>:</h4>
<p>why couldn't <code>Stdin::lock()</code> return <code>StdinLock&lt;'static&gt;</code>? the only ref that <code>StdinLock</code> seems to hold is the <code>Mutex</code> (indirectly through <code>MutexGuard</code>, and the <code>Mutex</code>  is static</p>



<a name="239002557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239002557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239002557">(May 16 2021 at 20:04)</a>:</h4>
<p>ok, trying to replicate what <code>Stdin</code> does, it seems like a lifetime of <code>'static</code> would probably work? i think this might be a bug in <code>std::io</code>. is there something i'm missing? <a href="https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=3d5d7666e9ada98a6a6e4287ce783fcc">https://play.rust-lang.org/?version=nightly&amp;mode=debug&amp;edition=2018&amp;gist=3d5d7666e9ada98a6a6e4287ce783fcc</a></p>



<a name="239002943"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239002943" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239002943">(May 16 2021 at 20:10)</a>:</h4>
<p>i don't get it; why do any of the locked stdio handles take a lifetime parameter at all, if they're all going to reference a static <code>Mutex</code>?</p>



<a name="239007538"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239007538" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239007538">(May 16 2021 at 21:26)</a>:</h4>
<p><a href="https://github.com/rust-lang/rust/issues/85383">https://github.com/rust-lang/rust/issues/85383</a></p>



<a name="239010018"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239010018" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239010018">(May 16 2021 at 22:08)</a>:</h4>
<p>Perhaps an owned mutex was used in the past or the option to do so is supposed to be kept open.</p>



<a name="239011300"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239011300" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239011300">(May 16 2021 at 22:31)</a>:</h4>
<p>I'm not sure why when &amp;self = &amp;'a Stdin, self.inner, that resolves to 'a &amp;'static Mutex&lt;...&gt; is not being lifted to 'static &amp;'static Mutex&lt;...&gt;. I shot a more detailed comment in the issue - seems to me that if reference's underlying type does not reference non-static lifetimes, 'a &amp;'static X can be lifted to 'static &amp;'static X.<br>
AFAICT that's an application of theorem from modal logic: if somewhere it is true that X is true everywhere, then X is true everywhere.<br>
(in this case, "somewhen" I guess).</p>



<a name="239011626"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239011626" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239011626">(May 16 2021 at 22:36)</a>:</h4>
<p>What do you mean by <code>'a &amp;'static X</code>? Usually that lifetime would be attached to something like <code>&amp;'a &amp;'static X</code>. Note that from <code>&amp;'a &amp;'static X</code> you can get <code>&amp;'static X</code> (by dereferencing) but not <code>&amp;'static &amp;'static X</code> (because the pointer to the static may not itself have static lifetime). Similarly, from <code>&amp;'a mut &amp;'static X</code> you can get <code>&amp;'static X</code> but not <code>&amp;'static mut &amp;'static X</code>.</p>



<a name="239011730"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239011730" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239011730">(May 16 2021 at 22:38)</a>:</h4>
<p>In your example, if <code>&amp;self: &amp;'a Stdin</code>, then <code>&amp;self.inner: &amp;'a &amp;'static Mutex&lt;...&gt;</code> and <code>self.inner: &amp;'static Mutex&lt;...&gt;</code>. I don't think the modal logic analogy works here.</p>



<a name="239011753"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239011753" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239011753">(May 16 2021 at 22:39)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239011626">said</a>:</p>
<blockquote>
<p>What do you mean by <code>'a &amp;'static X</code>? Usually that lifetime would be attached to something like <code>&amp;'a &amp;'static X</code>. Note that from <code>&amp;'a &amp;'static X</code> you can get <code>&amp;'static X</code> (by dereferencing) but not <code>&amp;'static &amp;'static X</code> (because the pointer to the static may not itself have static lifetime). Similarly, from <code>&amp;'a mut &amp;'static X</code> you can get <code>&amp;'static X</code> but not <code>&amp;'static mut &amp;'static X</code>.</p>
</blockquote>
<p>Hm, yeah, upon further reflection in makes no sense to assign lifetimes to values, only to variables and references.<br>
Then, I'm not sure, why with T: struct {inner: &amp;'static U }; self.inner resolves to &amp;'a U when &amp;self is &amp;'a T.</p>



<a name="239011840"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239011840" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239011840">(May 16 2021 at 22:40)</a>:</h4>
<p>You can actually get both <code>&amp;'a U</code> and <code>&amp;'static U</code> from <code>&amp;'a &amp;'static U</code>: the first comes from reborrowing (i.e. <code>&amp;**x</code>) and the second comes from dereferencing (<code>*x</code>)</p>



<a name="239011928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239011928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239011928">(May 16 2021 at 22:42)</a>:</h4>
<p>If you want to be really explicit about copying the reference out you could write <code>(*self).inner.clone()</code> but usually rust just does the right thing here</p>



<a name="239012080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012080">(May 16 2021 at 22:45)</a>:</h4>
<p>Oh. Since return type is parametrized by a lifetime, it inherits &amp;'a T lifetime - it's the function signature that limits the lifetime here. I'm dumb.<br>
Then I guess the error is that borrowck doesn't extend temporary's lifetime till the end of main(), even though it totally could?</p>



<a name="239012126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012126">(May 16 2021 at 22:46)</a>:</h4>
<p>It does, under certain circumstances, this is called temporary promotion IIRC</p>



<a name="239012155"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012155" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012155">(May 16 2021 at 22:47)</a>:</h4>
<p>But normally the temporary will be destroyed at the end of the statement and the lock would be useless</p>



<a name="239012203"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012203" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012203">(May 16 2021 at 22:47)</a>:</h4>
<p>In fact, I think that's why the "fake" lifetime on <code>StdioLock</code> is there - it lets the borrow checker prevent this situation</p>



<a name="239012293"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012293" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012293">(May 16 2021 at 22:49)</a>:</h4>
<p><a href="https://rust-lang.github.io/rfcs/0066-better-temporary-lifetimes.html">https://rust-lang.github.io/rfcs/0066-better-temporary-lifetimes.html</a> this seems to be the RFC that references a similar behaviour - TS, you could probably weigh in on that and link your issue to the tracking issue.</p>



<a name="239012385"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012385" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012385">(May 16 2021 at 22:50)</a>:</h4>
<p>see also <a href="https://doc.rust-lang.org/reference/destructors.html#temporary-lifetime-extension">https://doc.rust-lang.org/reference/destructors.html#temporary-lifetime-extension</a></p>



<a name="239012404"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012404" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012404">(May 16 2021 at 22:51)</a>:</h4>
<p>Yeah, but that's incredibly underspecified, "sometimes it happens". RFC is more precise.</p>



<a name="239012419"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012419" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012419">(May 16 2021 at 22:52)</a>:</h4>
<p>it specifies further down on the page</p>



<a name="239012545"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012545" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012545">(May 16 2021 at 22:54)</a>:</h4>
<p>in any case, <code>let x = (&amp;foo()).bar();</code> (usually written <code>let x = foo().bar();</code>) is explicitly mentioned as an example where the <code>foo()</code> temporary is <em>not</em> extended. Sometimes macros prefer to use <code>match (&amp;foo()).bar() { x =&gt; ... }</code> instead of <code>let</code> for this reason</p>



<a name="239012599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012599">(May 16 2021 at 22:55)</a>:</h4>
<p>Thanks, totally missed the counterexample.</p>



<a name="239012658"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012658" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012658">(May 16 2021 at 22:56)</a>:</h4>
<p>Assuming <code>Stdin</code> is built on <code>Mutex</code> and <code>StdinLock</code> on <code>MutexGuard</code>, it isn't possible to use <code>StdinLock&lt;'static&gt;</code> because that corresponds to <code>MutexGuard&lt;'static, T&gt;</code> which is a neverending lock. The destructor wouldn't be able to close the lock</p>



<a name="239012700"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239012700" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239012700">(May 16 2021 at 22:57)</a>:</h4>
<p>the lifetime in question is the critical section itself, not the validity of some piece of memory per se</p>



<a name="239013080"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239013080" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239013080">(May 16 2021 at 23:02)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239012700">said</a>:</p>
<blockquote>
<p>the lifetime in question is the critical section itself, not the validity of some piece of memory per se</p>
</blockquote>
<p>I'm not sure that's true? <a href="https://doc.rust-lang.org/src/std/sync/mutex.rs.html#194-197">https://doc.rust-lang.org/src/std/sync/mutex.rs.html#194-197</a> looks like <code>'a</code> applies to the <code>&amp;'a Mutex</code> and a bound on the contained type <code>T</code>?</p>



<a name="239013303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239013303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239013303">(May 16 2021 at 23:05)</a>:</h4>
<p>sure, but even if it only stored a raw pointer it would still want the lifetime for API purposes</p>



<a name="239013364"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239013364" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239013364">(May 16 2021 at 23:06)</a>:</h4>
<p>do you mean that because it's already  a part of the API, we can't remove the lifetime parameter from <code>StdinLock</code>?</p>



<a name="239013672"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239013672" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239013672">(May 16 2021 at 23:11)</a>:</h4>
<p>Well, looking at the API now there is nothing that exposes <code>Stdin -&gt; &amp;'static Stdin</code> or similar, so there could be resources associated to the return value of <code>stdin()</code></p>



<a name="239013739"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239013739" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239013739">(May 16 2021 at 23:12)</a>:</h4>
<p><code>Stdin</code> isn't even <code>Copy</code> or <code>Clone</code></p>



<a name="239013771"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239013771" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239013771">(May 16 2021 at 23:13)</a>:</h4>
<p>Plus this is an API over an OS dependent thing, so my guess is that this is trying to be conservative over different implementation strategies for different OSs</p>



<a name="239014691"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239014691" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239014691">(May 16 2021 at 23:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="411291">Taylor Yu</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239013364">said</a>:</p>
<blockquote>
<p>do you mean that because it's already  a part of the API, we can't remove the lifetime parameter from <code>StdinLock</code>?</p>
</blockquote>
<p>The return value of lock() needs to be temporary because it needs to drop and release the lock.</p>
<p>The 'a in MutexGuard applies to 'a Mutex, but it's actually a constraint: "Mutex needs to live at least as long as this guard". Mutex usually far outlives one of the guards.<br>
So the lifetime is needed because there's a nontrivial drop.</p>



<a name="239027371"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239027371" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239027371">(May 17 2021 at 03:11)</a>:</h4>
<p><code>Mutex::&lt;T&gt;::lock(&amp;self)</code> returns <code>LockResult&lt;MutexGuard&lt;'_,T&gt;</code>, so it seems to me that any <code>MutexGuard</code> resulting from <code>Mutex::lock()</code> would have its <code>'a</code> lifetime equal to that of the elided lifetime of the <code>&amp;self</code> reference of the original <code>Mutex</code>. is that right? so for a static <code>Mutex&lt;T&gt;</code>, that would mean <code>MutexGuard&lt;'static,T&gt;</code></p>



<a name="239029939"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239029939" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239029939">(May 17 2021 at 03:58)</a>:</h4>
<p>Yes, if you had a <code>&amp;'static Mutex&lt;T&gt;</code> you could derive a <code>MutexGuard&lt;'static, T&gt;</code>. However <code>Stdin</code> does not expose this implementation detail. If it wrapped a <code>Arc&lt;Mutex&lt;T&gt;&gt;</code> instead, then it would not be possible to get a <code>&amp;'static Mutex&lt;T&gt;</code> without leaking memory, so the analogue of <code>StdinLock</code> would need that lifetime parameter.</p>



<a name="239030645"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239030645" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239030645">(May 17 2021 at 04:05)</a>:</h4>
<p>(Earlier I said that <code>'a</code> in <code>MutexGuard&lt;'a, T&gt;</code> is the critical section, but that's not quite right. <code>'a</code> is an upper bound on the critical section (the actual critical section is the lifetime of the guard object itself), and a lower bound on the lifetime of the shared reference <code>&amp;'a Mutex&lt;T&gt;</code>  passed to <code>lock()</code>, and indirectly the lifetime of the mutex itself.)</p>



<a name="239118102"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239118102" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239118102">(May 17 2021 at 16:16)</a>:</h4>
<p>ok, the compiler calls it a borrow even though it's really a lifetime constraint violation on the return type and no borrow of the inputs exists in the return type: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=84f6bb1b93633e45af71e8eab9fc44e9">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=84f6bb1b93633e45af71e8eab9fc44e9</a></p>



<a name="239120260"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239120260" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239120260">(May 17 2021 at 16:30)</a>:</h4>
<p>There's an implicit borrow on A, <em>and</em> a constraint that ties that borrow's lifetime to the return type's lifetime.<br>
We could call it a constraint violation, or we could say that the constraint forces the implicit borrow to live for too long.</p>



<a name="239121364"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239121364" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239121364">(May 17 2021 at 16:38)</a>:</h4>
<p>the borrow of <code>&amp;self</code> ends when the method returns, right? the only reason the compiler acts like the borrow lasts longer is the lifetime constraint on the return value</p>



<a name="239122027"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239122027" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239122027">(May 17 2021 at 16:42)</a>:</h4>
<p>anyway, i find the error message misleading in these sorts of situations, and it could use improvement. (i went digging into <code>std::io</code> internals looking trying to figure out what borrow was actually taking place, when it was really a lifetime constraint problem)</p>



<a name="239124105"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239124105" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239124105">(May 17 2021 at 16:55)</a>:</h4>
<p>As far as the compiler is concerned, you expressing a lifetime relationship via signature constraint <em>is</em> specifying a logical borrow - what you're saying is "this borrow to self ought to live at least as long as the return type's parameter." In other circumstances, that borrow would've been successfully extended.</p>
<p>It's tricky to modify this error message without accidentally breaking other cases when the only thing connecting self borrow lifetime to return type is a signature constraint (ie, when we're doing some unsafe stuff).</p>



<a name="239163931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239163931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239163931">(May 17 2021 at 21:34)</a>:</h4>
<p><span class="user-mention silent" data-user-id="411291">Taylor Yu</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239121364">said</a>:</p>
<blockquote>
<p>the borrow of <code>&amp;self</code> ends when the method returns, right? the only reason the compiler acts like the borrow lasts longer is the lifetime constraint on the return value</p>
</blockquote>
<p>No, in this case since the borrow is tied to the returned guard object the borrow doesn't end until the guard returned from the function is dropped.</p>



<a name="239164420"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239164420" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239164420">(May 17 2021 at 21:39)</a>:</h4>
<p>that tie is the result of the <code>StdinLock&lt;'_&gt;</code> in the return type, isn't it? if it were some other type that didn't contain any refs, the <code>&amp;self</code> borrow would end when the method returns, right?</p>



<a name="239164756"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239164756" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239164756">(May 17 2021 at 21:43)</a>:</h4>
<p>yes</p>



<a name="239164891"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239164891" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239164891">(May 17 2021 at 21:44)</a>:</h4>
<p>and remember that it's not necessarily that the type "contains refs", for all I know the internal implementation uses raw pointers everywhere. The <code>&lt;'a&gt;</code> is there for API purposes</p>



<a name="239165002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165002">(May 17 2021 at 21:45)</a>:</h4>
<p>the point is that the <code>StdinLock</code> object becomes invalid if the <code>Stdin</code> object it was derived from is moved, mutated, or goes out of scope</p>



<a name="239165137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165137">(May 17 2021 at 21:47)</a>:</h4>
<p>or at least that's what the API says. Since in reality <code>Stdin</code> wraps a <code>&amp;'static Mutex&lt;T&gt;</code>, it isn't any real harm to allow those things because mutation isn't a possibility, moves can be copies and it's just a reference so there is no drop</p>



<a name="239165217"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165217" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165217">(May 17 2021 at 21:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239165002">said</a>:</p>
<blockquote>
<p>the point is that the <code>StdinLock</code> object becomes invalid if the <code>Stdin</code> object it was derived from is moved, mutated, or goes out of scope</p>
</blockquote>
<p>i think in the current implementation, there's no reason for that to always be true. changing the signature to <code>lock() -&gt; StdinLock&lt;'static&gt;</code> might theoretically break some users, but i doubt it's significant in practice</p>



<a name="239165343"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165343" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165343">(May 17 2021 at 21:49)</a>:</h4>
<p>I think you are assuming more stability of the current implementation strategy than actually exists</p>



<a name="239165492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165492">(May 17 2021 at 21:50)</a>:</h4>
<p>i think it's also important to avoid surprising behavior for new users, especially behavior that isn't officially documented anywhere</p>



<a name="239165544"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165544" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165544">(May 17 2021 at 21:51)</a>:</h4>
<p>what if on some target we need <code>stdin()</code> to produce some data that is not shared by other calls to <code>stdin()</code> and which is accessible via the guard? In that case if lock returned <code>StdinLock&lt;'static&gt;</code> we would be stuck</p>



<a name="239165593"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165593" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165593">(May 17 2021 at 21:51)</a>:</h4>
<p>The current API is <em>conservative</em> against these possibilities</p>



<a name="239165688"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165688" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165688">(May 17 2021 at 21:52)</a>:</h4>
<p>If you want a <code>StdinLock&lt;'static&gt;</code> you can always leak the result of <code>stdin()</code></p>



<a name="239165695"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165695" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165695">(May 17 2021 at 21:52)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239165544">said</a>:</p>
<blockquote>
<p>what if on some target we need <code>stdin()</code> to produce some data that is not shared by other calls to <code>stdin()</code> and which is accessible via the guard? In that case if lock returned <code>StdinLock&lt;'static&gt;</code> we would be stuck</p>
</blockquote>
<p><code>Stdin</code> _is_ already documented to be a handle that references a shared global resource, so your hypothetical is contrary to official documentation</p>



<a name="239165727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165727">(May 17 2021 at 21:53)</a>:</h4>
<p>the handle itself might carry metadata about the call though</p>



<a name="239165905"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239165905" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239165905">(May 17 2021 at 21:55)</a>:</h4>
<p>for example it might look like:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">struct</span> <span class="nc">Stdin</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">mutex</span>: <span class="kp">&amp;</span><span class="o">'</span><span class="nb">static</span> <span class="nc">Mutex</span><span class="o">&lt;</span><span class="n">RawStdin</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">when_called</span>: <span class="nc">Instant</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>(assuming you turn on some kind of profiling feature in the standard library)</p>



<a name="239166032"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166032" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166032">(May 17 2021 at 21:56)</a>:</h4>
<p>this does not contradict "a handle that references a shared global resource"</p>



<a name="239166197"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166197" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166197">(May 17 2021 at 21:58)</a>:</h4>
<p>i think all these hypotheticals don't outweigh the benefit of producing behavior that's less surprising to new users</p>



<a name="239166263"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166263" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166263">(May 17 2021 at 21:58)</a>:</h4>
<p>I think the presented API is quite standard for mutex-like things</p>



<a name="239166325"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166325" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166325">(May 17 2021 at 21:59)</a>:</h4>
<p>there are lots of "guard objects" that have exactly this design: <code>RefCell</code>, <code>Mutex</code>, <code>RwLock</code> all use the same pattern</p>



<a name="239166396"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166396" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166396">(May 17 2021 at 22:00)</a>:</h4>
<p>Well, RFC for better temporary promotion would be the behaviour that's less surprising for new users.<br>
There's also an argument that current API does forbid "forever lock" (since there's no way to produce &amp;'static Stdin), which is kinda nice.</p>



<a name="239166486"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166486" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166486">(May 17 2021 at 22:00)</a>:</h4>
<p><span class="user-mention silent" data-user-id="412531">Alex Mobius</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239166396">said</a>:</p>
<blockquote>
<p>Well, RFC for better temporary promotion would be the behaviour that's less surprising for new users.<br>
There's also an argument that current API does forbid "forever lock" (since there's no way to produce &amp;'static Stdin), which is kinda nice.</p>
</blockquote>
<p>what do you mean by "temporary promotion"?</p>



<a name="239166492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166492">(May 17 2021 at 22:00)</a>:</h4>
<p>you can <code>mem::forget</code> a lock guard if you want to forever lock</p>



<a name="239166526"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166526" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166526">(May 17 2021 at 22:01)</a>:</h4>
<p><a href="https://rust-lang.github.io/rfcs/0066-better-temporary-lifetimes.html">https://rust-lang.github.io/rfcs/0066-better-temporary-lifetimes.html</a></p>



<a name="239166553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166553">(May 17 2021 at 22:01)</a>:</h4>
<p>that is a very old RFC that has already been implemented</p>



<a name="239166644"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166644" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166644">(May 17 2021 at 22:02)</a>:</h4>
<p>so if that's the better option then you are already experiencing "better"</p>



<a name="239166663"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166663" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166663">(May 17 2021 at 22:02)</a>:</h4>
<p>I have no idea what it was like before</p>



<a name="239166679"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166679" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166679">(May 17 2021 at 22:02)</a>:</h4>
<p>The tracking  issue is open. It even references the stdout lock case in the tracking issue.</p>



<a name="239166782"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166782" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166782">(May 17 2021 at 22:03)</a>:</h4>
<p>oh I see, the RFC was accepted but there was no implemetation</p>



<a name="239166798"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166798" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166798">(May 17 2021 at 22:03)</a>:</h4>
<p>See also: <a href="https://github.com/rust-lang/rust/issues/70844">https://github.com/rust-lang/rust/issues/70844</a></p>



<a name="239166907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239166907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239166907">(May 17 2021 at 22:04)</a>:</h4>
<p>i guess another alternative is to make forwarding methods on <code>Stdin</code> for the few methods that consume a <code>StdinLock</code> to produce iterators, so users can call them directly on <code>Stdin</code> instead</p>



<a name="239167598"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239167598" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239167598">(May 17 2021 at 22:10)</a>:</h4>
<p>Hm, the RFC apparently has a storied history. The accepted RFC is very vague about the implementation side of things, and niko wrote a more elaborated version here: <a href="https://github.com/nikomatsakis/rfcs/blob/rfc66-amendment/text/0066-better-temporary-lifetimes.md">https://github.com/nikomatsakis/rfcs/blob/rfc66-amendment/text/0066-better-temporary-lifetimes.md</a></p>



<a name="239167652"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239167652" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239167652">(May 17 2021 at 22:11)</a>:</h4>
<p>But I definitely agree with Alex that the issue here has more to do with temporary lifetime extension rules than <code>Stdin</code> itself</p>



<a name="239167847"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239167847" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239167847">(May 17 2021 at 22:13)</a>:</h4>
<p><span class="user-mention silent" data-user-id="411291">Taylor Yu</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239166907">said</a>:</p>
<blockquote>
<p>i guess another alternative is to make forwarding methods on <code>Stdin</code> for the few methods that consume a <code>StdinLock</code> to produce iterators, so users can call them directly on <code>Stdin</code> instead</p>
</blockquote>
<p>You can already do this, you don't need to create a lock to call <code>println!()</code>. The reason for <code>StdinLock</code> is if you want to share the same lock across multiple IO operations, in which case having methods on <code>Stdin</code> are defeating the purpose because they would take individual locks</p>



<a name="239168616"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239168616" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239168616">(May 17 2021 at 22:20)</a>:</h4>
<p>i think there are two(?) <code>BufRead</code> methods that it makes sense for beginners to call on <code>StdinLock</code> that aren't available on <code>Stdin</code>: <code>lines()</code> and <code>split()</code>. so right now, users who want to call those methods have to use <code>StdinLock</code> and deal with lifetime complications on what would seem like a very simple operation</p>



<a name="239169049"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239169049" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239169049">(May 17 2021 at 22:25)</a>:</h4>
<p>my particular use case was i wanted an iterator over lines of <code>Stdin</code>, so i very reasonably tried something like <code>let lines = io::stdin().lock().lines();</code>, based on what i read in the libstd documentation, and ran smack into a very non-obvious and confusing lifetime constraint problem</p>



<a name="239169159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239169159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239169159">(May 17 2021 at 22:26)</a>:</h4>
<p>Have you looked at RFC 66? It's about exactly this</p>



<a name="239169205"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239169205" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239169205">(May 17 2021 at 22:27)</a>:</h4>
<p>it's not great that it's been in implementation limbo for six years though</p>



<a name="239169337"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239169337" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239169337">(May 17 2021 at 22:29)</a>:</h4>
<p>it's not a lifetime issue, really. The lifetime mismatch is just how rust notices that there is an issue, but what is wrong is the destructor placement and even if you turned off the borrow checker that would still be wrong</p>



<a name="239169368"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239169368" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239169368">(May 17 2021 at 22:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239169205">said</a>:</p>
<blockquote>
<p>it's not great that it's been in implementation limbo for six years though</p>
</blockquote>
<p>exactly! i'm trying to suggest solutions that would hopefully help newcomers sooner than that RFC would likely get implemented</p>



<a name="239169572"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239169572" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239169572">(May 17 2021 at 22:31)</a>:</h4>
<p>The problem is that "when destructors run" is a stable part of the rust language, so it's not easy to mess with the rules without breaking a lot of code</p>



<a name="239169602"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239169602" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239169602">(May 17 2021 at 22:31)</a>:</h4>
<p>there was a pass at this a few weeks ago here on zulip</p>



<a name="239169720"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239169720" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239169720">(May 17 2021 at 22:32)</a>:</h4>
<p>it's a common complaint, but the reason the RFC stalled is because it's not proposing a solution so much as identifying a problem</p>



<a name="239170089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170089">(May 17 2021 at 22:36)</a>:</h4>
<p>i mean i'm guessing even a <code>Stdin::into_lock(self)-&gt;StdinLock&lt;'static&gt;</code> might help, though the naming is somewhat less friendly to newcomers</p>



<a name="239170100"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170100" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170100">(May 17 2021 at 22:36)</a>:</h4>
<p>The change you are proposing will not solve the problem at all, and in fact will make the eventual better solution not work for <code>Stdin</code>. The destructor will still run early, but you are letting the <code>StdinLock</code> object live on even though the parent <code>Stdin</code> object is gone. For a regular mutex that would be a memory error, but for <code>Stdin</code> that means exposing the fact that it's actually a global object. If we wanted to expose this then <code>Stdin</code> should just be a static variable</p>



<a name="239170145"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170145" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170145">(May 17 2021 at 22:36)</a>:</h4>
<p>but <code>Stdin</code> contains a ref to the mutex, not the mutex itself!</p>



<a name="239170214"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170214" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170214">(May 17 2021 at 22:37)</a>:</h4>
<p>If <code>io::stdin()</code> returned <code>&amp;'static Stdin</code> then there would be no problem</p>



<a name="239170323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170323">(May 17 2021 at 22:38)</a>:</h4>
<p>in which case <code>Stdin</code> could be either the mutex itself or a static reference to it as currently</p>



<a name="239170455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170455">(May 17 2021 at 22:40)</a>:</h4>
<p>the non-existence of a lifetime parameter on <code>Stdin</code> already implies that it contains no non-static references, right?</p>



<a name="239170501"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170501" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170501">(May 17 2021 at 22:40)</a>:</h4>
<p>Yes...</p>



<a name="239170545"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170545" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170545">(May 17 2021 at 22:40)</a>:</h4>
<p>but since it is an object it has a lifetime that the user has to manage</p>



<a name="239170570"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170570" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170570">(May 17 2021 at 22:41)</a>:</h4>
<p>and it is that lifetime <code>'a</code> that ends up in <code>StdinLock&lt;'a&gt;</code></p>



<a name="239170587"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170587" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170587">(May 17 2021 at 22:41)</a>:</h4>
<p>and that is the lifetime that is cut short when you don't use enough let bindings</p>



<a name="239170663"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170663" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170663">(May 17 2021 at 22:42)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239170570">said</a>:</p>
<blockquote>
<p>and it is that lifetime <code>'a</code> that ends up in <code>StdinLock&lt;'a&gt;</code></p>
</blockquote>
<p>but that's an unnecessarily strict constraint on the lifetime of the return value given that <code>Stdin</code> contains only a static reference</p>



<a name="239170727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170727">(May 17 2021 at 22:42)</a>:</h4>
<p>If <code>io::stdin() -&gt; &amp;'static Stdin</code> then the user is never actually given a <code>Stdin</code> object which needs to be destroyed, and calling <code>lock()</code> on it will produce <code>StdinLock&lt;'static&gt;</code> like you want</p>



<a name="239170954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170954">(May 17 2021 at 22:45)</a>:</h4>
<blockquote>
<p>but that's an unnecessarily strict constraint on the lifetime of the return value given that Stdin contains only a static reference</p>
</blockquote>
<p>My argument so far has been that this unnecessarily strict constraint exists because the designers of the std API want the flexibility for the object returned from <code>stdin</code> to actually maintain some memory of its own. <code>io::stdin() -&gt; &amp;'static Stdin</code> is explicitly encoding that this is not the case, because the <code>Stdin</code> object here has to be global or otherwise leaked</p>



<a name="239170980"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239170980" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239170980">(May 17 2021 at 22:45)</a>:</h4>
<p>if it weren't for the <code>StdinLock&lt;'_&gt;</code> lifetime, then there is no connection between the lifetimes of any <code>Stdin</code> object and any <code>StdinLock</code> resulting from <code>Stdin::lock()</code>. and there is no memory safety issue because <code>Stdin::lock()</code> only ever produces a lock based on a static mutex</p>



<a name="239171131"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171131" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171131">(May 17 2021 at 22:46)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239170954">said</a>:</p>
<blockquote>
<p>My argument so far has been that this unnecessarily strict constraint exists because the designers of the std API want the flexibility for the object returned from <code>stdin</code> to actually maintain some memory of its own. <code>io::stdin() -&gt; &amp;'static Stdin</code> is explicitly encoding that this is not the case, because the <code>Stdin</code> object here has to be global or otherwise leaked</p>
</blockquote>
<p>where is this documented as the intent of the designers? or are you speculating?</p>



<a name="239171187"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171187" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171187">(May 17 2021 at 22:47)</a>:</h4>
<p>It is extrapolating from the shape of the API. Why else would an object that wraps a static reference not be copy or clone?</p>



<a name="239171292"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171292" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171292">(May 17 2021 at 22:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F/near/239171187">said</a>:</p>
<blockquote>
<p>It is extrapolating from the shape of the API. Why else would an object that wraps a static reference not be copy or clone?</p>
</blockquote>
<p>maybe an accident of history, probably due to the shape of a prior implementation that has evolved</p>



<a name="239171293"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171293" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171293">(May 17 2021 at 22:48)</a>:</h4>
<p>that's a pretty unusual choice for a rust API, so I find it unlikely to be an accident</p>



<a name="239171323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171323">(May 17 2021 at 22:49)</a>:</h4>
<blockquote>
<p>probably due to the shape of a prior implementation that has evolved</p>
</blockquote>
<p>Yes, evolution constraints are a thing, <em>especially</em> for std</p>



<a name="239171343"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171343" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171343">(May 17 2021 at 22:49)</a>:</h4>
<p>better to not promise too much</p>



<a name="239171362"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171362" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171362">(May 17 2021 at 22:49)</a>:</h4>
<p>see <a href="https://github.com/rust-lang/rust/pull/77154">https://github.com/rust-lang/rust/pull/77154</a></p>



<a name="239171368"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171368" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171368">(May 17 2021 at 22:49)</a>:</h4>
<p>like that <code>Stdin</code> and <code>StdinLock</code> do not have related lifetimes, or <code>Stdin</code> is actually a global object</p>



<a name="239171521"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171521" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171521">(May 17 2021 at 22:51)</a>:</h4>
<p>See, that's exactly the kind of implementation change that would not be possible with a wide API of the kind you want</p>



<a name="239171642"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171642" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171642">(May 17 2021 at 22:52)</a>:</h4>
<p>my interpretation is that a prior implementation <em>did</em> use <code>Arc</code>, so the distinct <code>Stdin</code> object was required, but that approach was abandoned, and now we have this partially-static implementation by accident (or because the <code>Arc</code>-based implementation boxed them in API-wise)</p>



<a name="239171975"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239171975" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239171975">(May 17 2021 at 22:55)</a>:</h4>
<p>I agree. Imagine if we had to go in the other direction though, or suppose that that refactor didn't work on some target. With today's API that would be no problem, nothing to bother users about, while if we had this <code>'static</code> stuff in the public API then it would be a problem</p>



<a name="239172068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239172068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239172068">(May 17 2021 at 22:56)</a>:</h4>
<p>That's what API stability is all about</p>



<a name="239172164"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239172164" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Mobius <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239172164">(May 17 2021 at 22:57)</a>:</h4>
<p>The reason I linked the RFC wasn't "yeah they're working on it", btw, but rather "this problem has a history, maybe we can meaningfully contribute to its solution instead of trying to rephrase an error message here"</p>



<a name="239173345"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239173345" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239173345">(May 17 2021 at 23:09)</a>:</h4>
<p>i still think that the E0716 text could be better. or maybe add more details to its extended error explanation about how the lifetimes of return values can effectively extend a borrow of the inputs</p>



<a name="239278390"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239278390" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Taylor Yu [they/she] <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239278390">(May 18 2021 at 15:57)</a>:</h4>
<p>do borrow checking or lifetime validation cross function call boundaries? i seem to recall that type inference does not</p>



<a name="239296509"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239296509" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> The 8472 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239296509">(May 18 2021 at 17:49)</a>:</h4>
<p>they don't</p>



<a name="239303201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239303201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239303201">(May 18 2021 at 18:31)</a>:</h4>
<p>borrow checking across function calls is mediated by lifetime annotations on function signatures</p>



<a name="239331473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/What%20does%20StdinLock%20borrow%20from%20Stdin%3F/near/239331473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/What.20does.20StdinLock.20borrow.20from.20Stdin.3F.html#239331473">(May 18 2021 at 21:51)</a>:</h4>
<p>i once had cause to make a combination struct that put the Stdin and StdinLock in the same thing by just transmuting the lock to be 'static and keeping both in ManuallyDrop and then undoing it all very carefully.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>